home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / Apps / DevTools / eText5 / Source / eTURLink.subproj / eTURLink.m < prev    next >
Encoding:
Text File  |  1995-08-04  |  8.9 KB  |  307 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //    FILENAME:    eTURLink.h 
  3. //    SUMMARY:    Implementation of a URL Annotation
  4. //    SUPERCLASS:    eTImage
  5. //    INTERFACE:    None
  6. //    PROTOCOLS:    <Annotation,HTMDSupport,ASCIISupport,LaTeXSupport,Tool,
  7. //                InspectableTarget>
  8. //    AUTHOR:        Rohit Khare
  9. //    COPYRIGHT:    (c) 1994 California Institure of Technology, eText Project
  10. ///////////////////////////////////////////////////////////////////////////////
  11. //    IMPLEMENTATION COMMENTS
  12. //        Holds an URLrep and tries to NXPerformService("Open URL").
  13. //        Tries to lookup an icon based on the scheme of the URL if possible
  14. ///////////////////////////////////////////////////////////////////////////////
  15. //    HISTORY
  16. //    02/04/95:    Added support to create .uri files; draggability
  17. //  02/04/95:    Modified to support new services (SpiderWoman, Omni .9)
  18. //    10/30/94:    Modified to support <InspectableTarget>
  19. //  07/20/94:    Minimal Creation
  20. ///////////////////////////////////////////////////////////////////////////////
  21.  
  22. #import "eTURLink.h"
  23. #define _eTURLinkVERSION    10
  24.  
  25. @implementation eTURLink
  26. //    char *URLRep;
  27.  
  28. - setURL: (const char *) newURL
  29. {    
  30.     URLRep = realloc(URLRep,(strlen(newURL)+1)*sizeof(char));
  31.     strcpy(URLRep, newURL);
  32.     [etDoc touch];
  33.     return self;
  34. }
  35. - (char *) URL {return URLRep;}
  36.  
  37. + toolAwake:theApp
  38. {
  39.     char        buf[MAXPATHLEN];
  40.     NXBundle    *bundle;
  41.     id             icon=nil;
  42.  
  43.     bundle = [NXBundle bundleForClass:[eTURLink class]];
  44.     // we should register a whole bunch of images here: "Gopher", "News",etc
  45.     if ([bundle getPath:buf forResource:"eTURLinkIcon" ofType:"tiff"] ) {
  46.         icon=[[NXImage alloc] initFromFile:buf];
  47.         [icon setName:"eTURLinkIcon"];
  48.     } else {
  49.         NXLogError("Image not found: eTURLinkIcon");
  50.     }    
  51.     [theApp   registerAnnotation: [eTURLink class] 
  52.                             name: "eTURLink"
  53.                     RTFDirective: "eTURLink"
  54.                        menuLabel: "HTML/Insert eTURLink"
  55.                          menuKey: '\0'
  56.                         menuIcon: (NXImage *) icon];
  57.  
  58.     [theApp registerType:NXCreateFileContentsPboardType(".uri") for:[eTURLink class]];
  59.     [theApp registerType:URIPboardType for:[eTURLink class]];
  60.     [theApp registerType:OWPboardType for:[eTURLink class]];
  61.  
  62.     return self;
  63. }
  64.  
  65. - init
  66. {
  67. #define DEFAULT "http://www.w3.org/"
  68.     [super init];
  69.     [self setUsesButtonStyle:NO];
  70.     [self setDraggable:YES];
  71.     [self setImageComponent:[eTImageComponent newImageNamed:"eTURLinkIcon"]];
  72.     URLRep = (char *)malloc((strlen(DEFAULT)+1)*sizeof(char));
  73.     strcpy(URLRep, DEFAULT);
  74.     return self;
  75. }
  76.  
  77. - initFromPboard:thePboard inDoc:theDoc linked:(BOOL) linked
  78. {
  79.     NXAtom foundType;
  80.     NXAtom supportedTypes[4] = {URIPboardType, OWPboardType,
  81.                                 NXFilenamePboardType,
  82.                                 NXFileContentsPboardType};
  83.  
  84.     [super initFromPboard:thePboard inDoc:theDoc linked:linked];
  85.     [imageComponent setDoc:etDoc];
  86.     [self setDescription:"here"];
  87.  
  88.     // first, we want to check for OW url drag types.
  89.     foundType = [thePboard findAvailableTypeFrom:supportedTypes num:4];
  90.  
  91.     if (foundType == NXFilenamePboardType) {
  92.         // can we derive a .uri file name? if not, puke
  93.         char    *path;
  94.         int        len;
  95.  
  96.         [thePboard readType:NXFilenamePboardType data:&path length:&len];
  97.         // we only process _ONE_ filename; this defeats the tab-separation
  98.         if (index(path, '\t')) *index(path, '\t')=0;
  99.         if (rindex(path, '.') && !strcmp(rindex(path, '.'), "."URI_EXT)) {
  100.             NXStream *s;
  101.             
  102.             // OK, we have a .uri path: bring the contents in, and path as title.
  103.             s = NXMapFile(path, NX_READONLY);
  104.             if (s) {
  105.                 char *data, *url;
  106.                 int len, maxlen;
  107.                 
  108.                 NXGetMemoryBuffer(s, &data, &len, &maxlen);
  109.                 if (!strncmp(data, "URL:",4)) url = data+4;
  110.                     else if (!strncmp(data, "<URL:",5)) url = data+5;
  111.                     else url = data;
  112.                 [self setURL:url];
  113.                 NXCloseMemory(s, NX_FREEBUFFER);
  114.             }
  115.             *rindex(path, '.') = '\0';
  116.             [self setDescription:path];
  117.             [self setCaptionMode];
  118.         }
  119.         [thePboard deallocatePasteboardData:path length:len];
  120.     } else if (foundType == NXFileContentsPboardType) {
  121.         NXLogError("Eeek! Unimplemented: FileContentsPboard for eTURLink.");
  122.     } else if (foundType == URIPboardType) {
  123.         // Note that we can't yet handle multiple URLs
  124.         char *data, *url;
  125.         int len, maxlen;
  126.         NXStream *s;
  127.         
  128.         s = [thePboard readTypeToStream:URIPboardType];
  129.         if (s) {
  130.             NXGetMemoryBuffer(s, &data, &len, &maxlen);
  131.             if (!strncmp(data, "URL:",4)) url = data+4;
  132.                 else if (!strncmp(data, "<URL:",5)) url = data+5;
  133.                 else url = data;
  134.             [self setURL:url];
  135.             NXCloseMemory(s, NX_FREEBUFFER);
  136.         }
  137.         s = [thePboard readTypeToStream:URITitlePboardType];
  138.         if (s) {
  139.             NXGetMemoryBuffer(s, &data, &len, &maxlen);
  140.             [self setDescription:data];
  141.             [self setCaptionMode];
  142.             NXCloseMemory(s, NX_FREEBUFFER);
  143.         }
  144.     } else if (foundType == OWPboardType) {
  145.         // OmniWeb combatibility hemorrage... 
  146.         char *data;
  147.         int len;
  148.         
  149.         [thePboard readType:OWPboardType data:&data length:&len];
  150.         [self setURL:data];
  151.         [self setDescription:data];
  152.         [self setCaptionMode];
  153.         [thePboard deallocatePasteboardData:data length:len];
  154.     } else {
  155.         NXSelPt    begin, end;
  156.  
  157.         [theText getSel:&begin :&end];     // we know the sel exists because
  158.                                         // etApp checks acceptsAnnotation:
  159.         if (begin.cp != end.cp) {
  160.             char *buf = calloc((end.cp - begin.cp + 1) , sizeof(char));
  161.             [theText getSubstring:buf start:begin.cp length:(end.cp - begin.cp)];
  162.             [self setURL:buf];
  163.             free(buf);
  164.         }
  165.     }
  166.     return self;
  167. }
  168. - readRichText:(NXStream *)stream forView:view 
  169. {
  170.     int i;
  171.     char buf[MAXPATHLEN];
  172.     
  173.     NXScanf(stream, "%d ", &i);
  174.     if (i != _eTURLinkVERSION) {
  175.         // bad version block.
  176.      NXLogError("eTURLink found unparseable version %d at position %d",
  177.                     i, NXTell(stream));
  178.         return nil;
  179.     }
  180.     NXScanf(stream, "%d", &i); NXGetc(stream); //space-eater
  181.     if(i) NXRead(stream,buf,i);
  182.     buf[i]=0;
  183.     [self setURL:buf];
  184.     NXGetc(stream); // trailing space
  185.     [super readRichText:stream forView:view];
  186.     return self;
  187. }
  188.  
  189. - writeRichText:(NXStream *)stream forView:view
  190. {
  191.     NXPrintf(stream, "%d %d %s ", _eTURLinkVERSION, 
  192.              strlen(URLRep), URLRep);
  193.     [super writeRichText:stream forView:view];
  194.     return self;
  195. }
  196.  
  197. - writeASCIIRef:(NXStream *)stream forView:view
  198. {
  199.     NXPrintf(stream, "See %V.\n\t",URLRep);
  200.     [super writeASCIIRef:stream forView:view];
  201.     return self;
  202. }
  203.  
  204. - writeHTML:(NXStream *)stream forView: view
  205. {
  206.     // always generates an icon -- we _ought_ to provide for an alternate
  207.     // associated label.
  208.     NXPrintf(stream,"<A HREF=\"%s\">", URLRep);
  209.     [super writeHTML:stream forView:view];
  210.     NXPrintf(stream,"</A>");
  211.     return self;
  212. }
  213.  
  214. - writeLaTeX:(NXStream *)stream forView: view
  215. {
  216.     [super writeLaTeX:stream forView:view];
  217.     NXPrintf(stream,"\n\\footnote{See {\\tt %w}}\n",URLRep);
  218.     return self;
  219. }
  220.  
  221. - click:(NXEvent*)e
  222.     { return self;}
  223. - doubleClick:(NXEvent *)e
  224. {
  225.     id    thePB;
  226.     
  227.     thePB = [Pasteboard newUnique];
  228.     [thePB declareTypes:&NXAsciiPboardType num:1 owner:nil];
  229.     [thePB writeType:NXAsciiPboardType data:URLRep length:strlen(URLRep)];
  230.     if (!NXPerformService("Open URL", thePB) &&
  231.         !NXPerformService("OmniWeb/Open URL", thePB) &&
  232.         !NXPerformService("SpiderWoman/Open URL", thePB))
  233.         NXRunAlertPanel("eTURLink","Could not open a "URI_EXT" file (using services): %s.", "OK", NULL, NULL, URLRep);
  234.     return self;
  235. }
  236. - inspect:(NXEvent*)e
  237.     { [[NXApp inspector] inspect:self];return self;}
  238. - (id <Inspectable>) inspectableDelegate {
  239.     return [[eTURLinkUI new] setAnnotation:self]; }
  240.  
  241. - setImageComponent:newImageComponent
  242. {
  243.     const char *name;
  244.     
  245.     name = [[newImageComponent theImage] name];
  246.     if (name && !strcmp(name,"eTURLinkIcon"))
  247.         usesButtonStyle = NO;
  248.     else
  249.         usesButtonStyle = YES;
  250.     return [super setImageComponent:newImageComponent];
  251. }
  252.  
  253. - drag: (Pasteboard *)draggingPboard image: (NXImage **)proxyImage
  254. {
  255.     char     filename[MAXPATHLEN], filteredTitle[MAXPATHLEN], *title;
  256.     NXAtom     types[3] = {URIPboardType, NXAsciiPboardType, NXFilenamePboardType};
  257.     NXStream *b;
  258.     int         i;
  259.     
  260.     // write out .uri file in /tmp
  261.     title = [self description];
  262.     if (title && *title) sprintf(filteredTitle, "%s."URI_EXT, title);
  263.     else sprintf(filteredTitle, "%s."URI_EXT, URLRep);
  264.     
  265.     // filter out /es
  266.     for (i=0; filteredTitle[i]; i++) if (filteredTitle[i] == '/') filteredTitle[i] = '_';
  267.     
  268.     sprintf(filename, "/tmp/%s", filteredTitle);
  269.     
  270.     [draggingPboard declareTypes:types num:3 owner:nil];
  271.     [draggingPboard writeType: NXFilenamePboardType data: filename
  272.                     length: strlen(filename)];
  273.  
  274.     b = NXOpenMemory(NULL, 0, NX_READWRITE);
  275.     NXPrintf(b, "%V", URLRep);
  276.     NXSeek(b, 0, NX_FROMSTART);
  277.     [draggingPboard writeType: NXAsciiPboardType fromStream:b];
  278.  
  279.     NXSeek(b, 0, NX_FROMSTART);
  280.     if (strncmp(URLRep, "URL:",4)) NXPrintf(b, "URL:%V", URLRep);
  281.     else NXPrintf(b, "%V", URLRep);;
  282.     NXSeek(b, 0, NX_FROMSTART);
  283.     [draggingPboard writeType: URIPboardType fromStream:b];
  284.  
  285.     NXSeek(b, 0, NX_FROMSTART);
  286.     NXSaveToFile(b, filename);
  287.     NXCloseMemory(b, NX_FREEBUFFER);
  288.  
  289.     *proxyImage = [NXImage findImageNamed:NXUniqueString("eTURLinkIcon")];
  290.     return self;
  291. }
  292.  
  293. - addToPboard: pboard
  294. {
  295.     char     buf[MAXPATHLEN];
  296.     NXStream *b;
  297.     
  298.     b = NXOpenMemory(buf, MAXPATHLEN, NX_READWRITE);
  299.     if (strncmp(URLRep, "URL:",4)) NXPrintf(b, "URL:%V", URLRep);
  300.     else NXPrintf(b, "%V", URLRep);;
  301.     NXSeek(b, 0, NX_FROMSTART);
  302.     [pboard addTypes:&URIPboardType num:1 owner:nil];
  303.     [pboard writeType:URIPboardType fromStream:b];
  304.     NXClose(b);
  305. }
  306.  
  307. @end